package com.cbt.cbtBlog.util;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class LucenceUtil {
   public static String indexPath = "index";
   private String path;
   private Analyzer ikAnalyzer = new MyIKAnalyzer();
   private String idField;
   private String[] textFields;

   public LucenceUtil(String className, String idField, String[] textFields) {
      this.path = indexPath + "/" + className;
      this.idField = idField;
      this.textFields = textFields;
   }

   public <T> void add(Class<T> c, List<T> objects) {
      IndexWriter writer = null;

      try {
         Directory index = FSDirectory.open(Paths.get(this.path));
         writer = new IndexWriter(index, new IndexWriterConfig(this.ikAnalyzer));
         Iterator var5 = objects.iterator();

         while(var5.hasNext()) {
            T object = (T) var5.next();
            Document doc = new Document();
            doc.add(new StringField(this.idField, this.getValue(c, object, this.idField), Store.YES));
            String[] var8 = this.textFields;
            int var9 = var8.length;

            for(int var10 = 0; var10 < var9; ++var10) {
               String textField = var8[var10];
               doc.add(new TextField(textField, this.getValue(c, object, textField), Store.YES));
            }

            writer.addDocument(doc);
         }
      } catch (IOException var15) {
         var15.printStackTrace();
      } finally {
         this.closeAll(writer, (IndexReader)null);
      }

   }

   public <T> void add(Class<T> c, T object) {
      IndexWriter writer = null;

      try {
         Directory index = FSDirectory.open(Paths.get(this.path));
         writer = new IndexWriter(index, new IndexWriterConfig(this.ikAnalyzer));
         Document doc = new Document();
         doc.add(new StringField(this.idField, this.getValue(c, object, this.idField), Store.YES));
         String[] var6 = this.textFields;
         int var7 = var6.length;

         for(int var8 = 0; var8 < var7; ++var8) {
            String textField = var6[var8];
            doc.add(new TextField(textField, this.getValue(c, object, textField), Store.YES));
         }

         writer.addDocument(doc);
      } catch (IOException var13) {
         var13.printStackTrace();
      } finally {
         this.closeAll(writer, (IndexReader)null);
      }

   }

   public void add(List<Document> docs) {
      IndexWriter writer = null;

      try {
         Directory index = FSDirectory.open(Paths.get(this.path));
         writer = new IndexWriter(index, new IndexWriterConfig(this.ikAnalyzer));
         Iterator var4 = docs.iterator();

         while(var4.hasNext()) {
            Document doc = (Document)var4.next();
            writer.addDocument(doc);
         }
      } catch (IOException var9) {
         var9.printStackTrace();
      } finally {
         this.closeAll(writer, (IndexReader)null);
      }

   }

   public <T> void update(Class<T> c, T object) {
      IndexWriter writer = null;

      try {
         Directory index = FSDirectory.open(Paths.get(this.path));
         writer = new IndexWriter(index, new IndexWriterConfig(this.ikAnalyzer));
         Document doc = new Document();
         doc.add(new StringField(this.idField, this.getValue(c, object, this.idField), Store.YES));
         String[] var6 = this.textFields;
         int var7 = var6.length;

         for(int var8 = 0; var8 < var7; ++var8) {
            String textField = var6[var8];
            doc.add(new TextField(textField, this.getValue(c, object, textField), Store.YES));
         }

         writer.updateDocument(new Term(this.idField, this.getValue(c, object, this.idField)), doc);
      } catch (IOException var13) {
         var13.printStackTrace();
      } finally {
         this.closeAll(writer, (IndexReader)null);
      }

   }

   public void update(Document doc, Term term) {
      IndexWriter writer = null;

      try {
         Directory index = FSDirectory.open(Paths.get(this.path));
         writer = new IndexWriter(index, new IndexWriterConfig(this.ikAnalyzer));
         writer.updateDocument(term, doc);
      } catch (IOException var8) {
         var8.printStackTrace();
      } finally {
         this.closeAll(writer, (IndexReader)null);
      }

   }

   public void delete(Term term) {
      IndexWriter writer = null;

      try {
         Directory index = FSDirectory.open(Paths.get(this.path));
         writer = new IndexWriter(index, new IndexWriterConfig(this.ikAnalyzer));
         writer.deleteDocuments(new Term[]{term});
      } catch (IOException var7) {
         var7.printStackTrace();
      } finally {
         this.closeAll(writer, (IndexReader)null);
      }

   }

   public void delete(String id) {
      IndexWriter writer = null;

      try {
         Directory index = FSDirectory.open(Paths.get(this.path));
         writer = new IndexWriter(index, new IndexWriterConfig(this.ikAnalyzer));
         writer.deleteDocuments(new Term[]{new Term(this.idField, id)});
      } catch (IOException var7) {
         var7.printStackTrace();
      } finally {
         this.closeAll(writer, (IndexReader)null);
      }

   }

   public void deleteAll() {
      IndexWriter writer = null;

      try {
         Directory index = FSDirectory.open(Paths.get(this.path));
         writer = new IndexWriter(index, new IndexWriterConfig(this.ikAnalyzer));
         writer.deleteAll();
      } catch (IOException var6) {
         var6.printStackTrace();
      } finally {
         this.closeAll(writer, (IndexReader)null);
      }

   }

   public List<Document> search(String[] fields, String keyword, int limit) {
      IndexReader reader = null;
      ArrayList result = new ArrayList();

      try {
         Directory index = FSDirectory.open(Paths.get(this.path));
         reader = DirectoryReader.open(index);
         IndexSearcher searcher = new IndexSearcher(reader);
         Query query = (new MultiFieldQueryParser(fields, this.ikAnalyzer)).parse(keyword);
         ScoreDoc[] scoreDocs = searcher.search(query, limit).scoreDocs;
         ScoreDoc[] var10 = scoreDocs;
         int var11 = scoreDocs.length;

         for(int var12 = 0; var12 < var11; ++var12) {
            ScoreDoc scoreDoc = var10[var12];
            int docId = scoreDoc.doc;
            Document doc = searcher.doc(docId);
            result.add(doc);
         }
      } catch (IOException var20) {
         var20.printStackTrace();
      } catch (ParseException var21) {
         var21.printStackTrace();
      } finally {
         this.closeAll((IndexWriter)null, reader);
      }

      return result;
   }

   public List<Document> search(String[] fields, String keyword, Float[] weights, int limit) {
      IndexReader reader = null;
      ArrayList result = new ArrayList();

      try {
         Directory index = FSDirectory.open(Paths.get(this.path));
         reader = DirectoryReader.open(index);
         IndexSearcher searcher = new IndexSearcher(reader);
         Map<String, Float> boosts = new HashMap();
         int i = 0;

         for(int len = Math.min(fields.length, weights.length); i < len; ++i) {
            boosts.put(fields[i], weights[i]);
         }

         Query query = (new MultiFieldQueryParser(fields, this.ikAnalyzer, boosts)).parse(keyword);
         ScoreDoc[] scoreDocs = searcher.search(query, limit).scoreDocs;
         ScoreDoc[] var12 = scoreDocs;
         int var13 = scoreDocs.length;

         for(int var14 = 0; var14 < var13; ++var14) {
            ScoreDoc scoreDoc = var12[var14];
            int docId = scoreDoc.doc;
            Document doc = searcher.doc(docId);
            result.add(doc);
         }
      } catch (IOException var22) {
         var22.printStackTrace();
      } catch (ParseException var23) {
         var23.printStackTrace();
      } finally {
         this.closeAll((IndexWriter)null, reader);
      }

      return result;
   }

   private <T> String getValue(Class<T> c, T object, String field) {
      String value = null;

      try {
         String getterName = "get" + Character.toUpperCase(field.charAt(0)) + field.substring(1);
         Method getter = c.getDeclaredMethod(getterName);
         value = String.valueOf(getter.invoke(object));
      } catch (NoSuchMethodException var7) {
         var7.printStackTrace();
      } catch (IllegalAccessException var8) {
         var8.printStackTrace();
      } catch (InvocationTargetException var9) {
         var9.printStackTrace();
      }

      return value;
   }

   private void closeAll(IndexWriter writer, IndexReader reader) {
      if (writer != null) {
         try {
            writer.close();
         } catch (IOException var5) {
            var5.printStackTrace();
         }
      }

      if (reader != null) {
         try {
            reader.close();
         } catch (IOException var4) {
            var4.printStackTrace();
         }
      }

   }
}
